Skip to content

feat: nested categories, i18n language filtering, and locale field in…#3

Open
yguerdat wants to merge 6 commits into
EcomGraduates:mainfrom
yguerdat:feature/nested-categories-and-i18n
Open

feat: nested categories, i18n language filtering, and locale field in…#3
yguerdat wants to merge 6 commits into
EcomGraduates:mainfrom
yguerdat:feature/nested-categories-and-i18n

Conversation

@yguerdat

Copy link
Copy Markdown

… article responses

  • GET /categories now returns a recursive tree (children array per node)
  • ?flat=1 param restores the flat list with parent_id for backward compat
  • ?lang= / ?locale= on /categories filters out categories with no articles in that locale (tree and flat modes)
  • GET /languages endpoint returns distinct locales of published articles
  • ?lang= / ?locale= on /search filters articles by locale (no param = all languages, backward compat)
  • All article responses now include a locale field (category, article, search, export endpoints)
  • resolveLocale() helper centralises lang > locale > mailbox default resolution across all endpoints

yguerdat and others added 6 commits March 10, 2026 18:56
… article responses

- GET /categories now returns a recursive tree (children array per node)
- ?flat=1 param restores the flat list with parent_id for backward compat
- ?lang= / ?locale= on /categories filters out categories with no articles in that locale (tree and flat modes)
- GET /languages endpoint returns distinct locales of published articles
- ?lang= / ?locale= on /search filters articles by locale (no param = all languages, backward compat)
- All article responses now include a `locale` field (category, article, search, export endpoints)
- `resolveLocale()` helper centralises lang > locale > mailbox default resolution across all endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…egory tree

The FreeScout KnowledgeBase module uses kb_category_id (not parent_id)
and getTree() returns a pre-built tree with children in ->categories.
Adapted buildCategoryTree/buildCategoryFlat to use this structure.
Added children to single category endpoint response.
Updated .gitignore to exclude SSH keys and .claude directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…oints

Consistent language filtering across all API endpoints via ?lang= or ?locale= parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ocale filtering

getArticlesSorted() returns an Eloquent Collection, not a plain array,
causing array_filter() to fail on the production server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… locale

Articles in the KB store locale in a JSON field ("l" key). Most existing
articles have an empty locale value. The lang filter was comparing empty
string to "fr", causing all articles to be excluded.

Now uses a localeMatches() helper that falls back to the mailbox default
locale when an article's locale is empty/null.

Also fixes search endpoint which was using a SQL WHERE on a non-existent
"locale" column — filtering is now done in PHP after fetching results.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r lang filtering

The locale accessor returns the "l" field from JSON which is often empty.
STATUS_PUBLISHED is 2 (not 1 as assumed), so most translated articles
were actually published.

New articleHasLocale() method inspects the raw JSON title to check if a
translation key exists (e.g. "de" key for German). For the default locale,
articles always match via the "v" (default value) key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant